package com.duojuhe.common.utils.sign;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.duojuhe.common.bean.DiyArrayList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.security.MessageDigest;
import java.util.*;

@Slf4j
public class SignUtils {
    //请求头标识
    public static final String SIGN_HEADER = "sign";

    /**
     * 获得请求头中的签名
     * @param request
     * @return
     */
    public static String getSignByRequest(HttpServletRequest request){
        //优先去请求头中获取sign值
       String headerSign = request.getHeader(SIGN_HEADER);
        if (StringUtils.isBlank(headerSign)){
            return request.getParameter(SIGN_HEADER);
        }else{
            return headerSign;
        }
    }

    /**
     * 获取签名值
     * 签名规则 MD5(appKey+Sort(params)+appSecret)
     * @param jsonStr json字符串
     * @param appKey 平台提供的appKey
     * @param appSecret 平台提供的密钥
     * @return 生成的签名值
     */
    public static String getSignStr(String jsonStr,String appKey,String appSecret) {
        log.info("【开放平台】签名请求json值：{}",jsonStr);
        SortedMap<String, Object> map = jsonToSortMap(jsonStr);
        StringBuilder stringBuffer = new StringBuilder();
        for (Map.Entry<String, Object> m : map.entrySet()) {
            Object o =  m.getValue();
            String value=null;
            if(o!=null){
                value = m.getValue().toString();
            }
            if (StringUtils.isBlank(value)) {
                continue;
            }
            // 或略掉的字段 sign字段
            if (SIGN_HEADER.toLowerCase().equals(value.toLowerCase())) {
                continue;
            }
            stringBuffer.append(m.getKey()).append("=").append(value).append("&");
        }
        log.info("【开放平台】待加密拼接值：{}",stringBuffer.toString());
        String endStr = appKey + stringBuffer.toString() + appSecret;
        String sign = getMD532(endStr).toLowerCase();
        log.info("【开放平台】最终加密值：{}", sign);
        return sign;
    }



    /**
     * 与三方tc交互使用 获取参数拼接串  Map<String, Object>
     *
     * @param
     * @return
     */
    public static String getSignStr(SortedMap<String, Object> smap) {
        StringBuilder stringBuffer = new StringBuilder();
        for (Map.Entry<String, Object> m : smap.entrySet()) {
            Object o =  m.getValue();
            String value=null;
            if(o!=null){
                value = m.getValue().toString();
            }
            if (StringUtils.isBlank(value)) {
                continue;
            }
            // 或略掉的字段 sign字段
            if (SIGN_HEADER.toLowerCase().equals(value.toLowerCase())) {
                continue;
            }
            stringBuffer.append(m.getKey()).append("=").append(value).append("&");
        }
        return stringBuffer.toString();
    }


    /**
     * 32位加密
     * @param str
     * @return
     */
    private static String getMD532(String str) {
        try {
            if (str != null) {
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(str.getBytes());
                byte[] b = md.digest();
                StringBuilder su = new StringBuilder();
                int offset = 0;
                for(int bLen = b.length; offset < bLen; ++offset) {
                    String haxHex = Integer.toHexString(b[offset] & 255);
                    if (haxHex.length() < 2) {
                        su.append("0");
                    }
                    su.append(haxHex);
                }
                return su.toString();
            } else {
                return "";
            }
        } catch (Exception var7) {
            log.error("get md5 value fail", var7);
            return "";
        }
    }

    /**
     * 将json字符串转换成map对象
     *
     * @param json
     * @return
     */
    public static SortedMap<String, Object> jsonToSortMap(String json) {
        if(StringUtils.isBlank(json)){
            return new TreeMap<String, Object>();
        }
        JSONObject obj = (JSONObject) JSONObject.parse(json);
        return jsonToSortedMap(obj);
    }


    /**
     * 将JSONObject转换成map对象
     *
     * @param
     * @return
     */
    private static Map<String, Object> jsonToMap(JSONObject obj) {
        Set<?> set = obj.keySet();
        Map<String, Object> map = new HashMap<String, Object>(set.size());
        for (Object key : obj.keySet()) {
            Object value = obj.get(key);
            if (value instanceof JSONArray) {
                map.put(key.toString(),jsonToList((JSONArray) value));
            } else if (value instanceof JSONObject) {
                map.put(key.toString(),jsonToMap((JSONObject) value));
            } else {
                map.put(key.toString(),obj.get(key));
            }

        }
        return map;
    }

    /**
     * 将JSONArray对象转换成list集合
     *
     * @param jsonArr
     * @return
     */
    private static List<Object> jsonToList(JSONArray jsonArr) {
        List<Object> list = new DiyArrayList<Object>();
        for (Object obj : jsonArr) {
            if (obj instanceof JSONArray) {
                list.add(jsonToList((JSONArray) obj));
            } else if (obj instanceof JSONObject) {
                list.add(jsonToMap((JSONObject) obj));
            } else {
                list.add(obj);
            }
        }
        return list;
    }

    /**
     * 将JSONObject转换成map对象
     *
     * @param
     * @return
     */
    private static SortedMap<String, Object> jsonToSortedMap(JSONObject obj) {
        SortedMap<String, Object> map = new TreeMap<String, Object>();
        for (Object key : obj.keySet()) {
            Object value = obj.get(key);
            if (value instanceof JSONArray) {
                map.put(key.toString(),jsonToList((JSONArray) value));
            } else if (value instanceof JSONObject) {
                map.put(key.toString(),jsonToSortedMap((JSONObject) value));
            } else {
                map.put(key.toString(),obj.get(key));
            }
        }
        return map;
    }

}
